package com.yingxin.yx.framework.security;

import com.yingxin.yx.framework.security.handler.*;
import com.yingxin.yx.framework.security.matcher.AntMatchers;
import com.yingxin.yx.framework.security.matcher.filter.JwtAuthenticationTokenFilter;
import com.yingxin.yx.framework.security.provider.AppAccountAuthenticationProvider;
import com.yingxin.yx.framework.security.userdetails.AppAccountUserDetailsService;
import com.yingxin.yx.framework.user.core.IUserSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

/**
 * SpringSecurity配置类
 */
@Order(180)
@Configuration
public class AppAccountSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 自定义登录失败处理器
     */
    @Autowired
    private UserLoginFailureHandler userLoginFailureHandler;
    /**
     * 自定义注销成功处理器
     */
    @Autowired
    private UserLogoutSuccessHandler userLogoutSuccessHandler;
    /**
     * 自定义暂无权限处理器
     */
    @Autowired
    private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;


    /**
     * antMatchers
     */
    @Autowired
    private AntMatchers antMatchers;

    @Autowired
    private IUserSupport userSupport;

    /**
     * 自定义 UserDetailsService
     */
    @Autowired(required = false)
    private AppAccountUserDetailsService appAccountUserDetailsService;

    /**
     * 自定义登录逻辑验证器
     */
    @Autowired
    private AppAccountAuthenticationProvider appAccountAuthenticationProvider;

    /**
     * 自定义登录成功处理器
     */
    @Autowired
    private AppAccountLoginSuccessHandler appAccountLoginSuccessHandler;

    /**
     * 自定义未登录的处理器
     */
    @Autowired
    private UserAuthenticationEntryPointHandler userAuthenticationEntryPointHandler;

    /**
     * 加密方式
     *
     */
    /*
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
    */

    /*
    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder); // 设置密码加密方式
        return authenticationProvider;
    }
    */

    /**
     * 注入自定义PermissionEvaluator
     */
/*    @Bean
    public DefaultWebSecurityExpressionHandler userSecurityExpressionHandler() {
        DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
        handler.setPermissionEvaluator(new UserPermissionEvaluator());
        return handler;
    }*/

    /**
     * 配置登录验证逻辑
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        //这里可启用我们自己的登陆验证逻辑
        auth.authenticationProvider(appAccountAuthenticationProvider);
    }


    /**
     * 配置security的控制逻辑
     *
     * @Param http 请求
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/u/app/account/**").authorizeRequests()
                // 不进行权限验证的请求或资源(从配置文件中读取)
                .antMatchers(antMatchers.getPatterns()).permitAll()
                // .antMatchers("/*").permitAll()
                // 其他的需要登陆后才能访问
                .anyRequest().authenticated()
                .and()
                // 配置未登录自定义处理类
                .httpBasic().authenticationEntryPoint(userAuthenticationEntryPointHandler)
                .and()
                // 配置登录地址
                .formLogin()
                .loginProcessingUrl("/u/app/account/login")
                //.loginPage("")
                .usernameParameter("username")
                .passwordParameter("password")
                // 配置登录成功自定义处理类
                .successHandler(appAccountLoginSuccessHandler)
                // 配置登录失败自定义处理类
                .failureHandler(userLoginFailureHandler)
                /*.and()
                .rememberMe()
                .userDetailsService()
                .tokenRepository()
                .tokenValiditySeconds()*/
                .and()
                // 配置登出地址
                .logout()
                .logoutUrl("/login/userLogout")
                // 配置用户登出自定义处理类
                .logoutSuccessHandler(userLogoutSuccessHandler)
                .and()
                // 配置没有权限自定义处理类
                .exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler)
                .and()
                // 开启跨域
                .cors()
                .and()
                // 取消跨站请求伪造防护
                .csrf().disable();
        // 基于Token不需要session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // 禁用缓存
        http.headers().cacheControl();
        // 添加JWT过滤器
        http.addFilter(new JwtAuthenticationTokenFilter(authenticationManager(),
                userAuthenticationEntryPointHandler, appAccountUserDetailsService, userSupport));
    }

    @Override
    public void configure(WebSecurity web) {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers(antMatchers.getPatterns());
    }



}